#include "PipeCube.h"

using namespace Ogre;

PipeCube::PipeCube(Ogre::Vector3 location, GridNode* g, std::list<Ogre::MaterialPtr> materials, Ogre::MeshPtr cubePtr, int iD, Ogre::SceneNode* mySceneNode, int direction):Cube(location, "PipeCube", g, cubePtr, iD)
{
	pipeMaterials = materials;
	this->iD = iD;
	myGNode = g;
	currentFace = 0;
	degreesRotated = 0;
	isRotating = rotatingLeft = rotatingRight = rotatingForward = rotatingBackward = rotatingClock = rotatingCountClock = false;
	if( !myGNode )	//This is a start or end cube, need to make it all one direction
	{
		if( direction == Level::N || direction == Level::S )
		{
			for( int i = 0; i < 6; i++ )
			{
				for( int k = 0; k < 3; k++ )
				{
					for( int j = 0; j < 3; j++ )
					{
						if( (j == 0 || j == 2) && k == 1 )
							faces[i][j][k] = true;
						else
							faces[i][j][k] = false;
					}
				}
				figureOutTextures(i, 1, 0, 1, 2);
			}
		}
		else // direction is E or W
		{
			for( int i = 0; i < 6; i++ )
			{
				for( int k = 0; k < 3; k++ )
				{
					for( int j = 0; j < 3; j++ )
					{
						if( j == 1 && (k == 0 || k == 2) )
							faces[i][j][k] = true;
						else
							faces[i][j][k] = false;
					}
				}
			figureOutTextures(i, 0, 1, 2, 1);
			}
		}
	}
	else	//This is a non start or end cube, it is valid
		initializeFaces();
	for( int i = 0; i < 6; i++ )
		facePlaceHolder[i] = i;	//Initialize facePlaceHolder with all the positions at the starting positions

	std::stringstream sID;
	sID << iD;
	if(mySceneNode != NULL)
	{
		mCubeNode = mySceneNode;
		mCubeNode->attachObject(mCubeEntity);
		mCubeNode->setScale(.1015625f, .1015625f, .1015625f);
	}

	pipeMaterials = materials;
	//faceA->setMaterialName("Material00");
	//faceB->setMaterialName("Material01");
	//faceC->setMaterialName("Material02");
	//faceD->setMaterialName("Material03");
	//faceE->setMaterialName("Material04");
	//faceF->setMaterialName("Material00");	//doesn't want to load material 5 right now..
}


void PipeCube::initializeFaces()
{
	
	int hvTOhv = 2;	//horizontal/vertical to horizontal/vertical entrances
	int hvTOdi = 2; //horizontal/vertical to diagonal entrances
	int diTOdi = 2; //diagonal to diagonal entrances


	for( int i = 0; i < 6; i++ )
	{
		int p1x = rand()%3;
		int p1y = rand()%3;
		int p2x;
		int p2y;

		if( hvTOhv )
		{
			if( rand()%2 )	//we'll say that y wins for p1y if rand()%2 == 1
			{
				if(p1y == 1)
				{
					if( p1x == 1 )	//x can only be 0 or 2 when y is 1
						p1x = (rand()%2) * 2;	//else x is okay
				}
				else	//x can only be 1 when y is 
					p1x = 1;
			}
			else	//x wins
			{
				if(p1x == 1)	//y can either be 0 or 2 when x == 1
				{
					if( p1y == 1 )
						p1y = (rand()%2) * 2; //else y is okay
				}
				else			//y can only be 1 when x == 0 || x == 2
					p1y = 1;
			}

			do
			{
				p2x = rand()%3;
				p2y = rand()%3;

				if( rand()%2 )	//We'll give x the win for this one
				{
					if( p2x == 1 )
					{
						if( p2y == 1 )
							p2y = (rand()%2)*2;
					}
					else
						p2y = 1;
				}
				else
				{
					if( p2y == 1 )
					{
						if( p2x == 1 )
							p2x = (rand()%2)*2;
					}
					else
						p2x = 1;
				}
			} while(p2x == p1x && p2y == p1y);	//Check to make sure the exit is not the entrance and vice versa

			hvTOhv--;
		}
		else if( hvTOdi )
		{
			if( rand()%2 )	//we'll say that y wins for p1y if rand()%2 == 1
			{
				if(p1y == 1)
				{
					if( p1x == 1 )	//x can only be 0 or 2 when y is 1
						p1x = (rand()%2) * 2;
				}
				else	//x can only be 1 when y is 
					p1x = 1;
			}
			else	//x wins
			{
				if(p1x == 1)	//y can either be 0 or 2 when x == 1
				{
					if( p1y == 1 )
						p1y = (rand()%2) * 2;
				}
				else			//y can only be 1 when x == 0 || x == 2
					p1y = 1;
			}

			if(p1y == 0)
			{
				p2y = 2;
				p2x = (rand()%2) * 2;
			}
			else if(p1y == 1)
			{
				p2y = (rand()%2) * 2;
				if( p1x == 0 )
					p2x = 2;
				else
					p2x = 0;
			}
			else	//p1y == 2
			{
				p2y = 0;
				p2x = (rand()%2) * 2;
			}

			hvTOdi--;
		}
		else if( diTOdi )
		{
			p1x = (rand()%2) * 2;
			p1y = (rand()%2) * 2;

			do
			{
				p2x = (rand()%2) * 2;
				p2y = (rand()%2) * 2;
			} while(p2x == p1x && p2y == p1y);

			diTOdi--;
		}

		for( int j = 0; j < 3; j++ )
		{
			for( int k = 0; k < 3; k++ )
			{
				if( (p1x == k && p1y == j) || (p2x == k && p2y == j) )
					faces[i][j][k] = true;
				else
					faces[i][j][k] = false;
			}
		}

		//Set up the textures according to what face we're on and what p1x, p1y, p2x, p2y are
		figureOutTextures( i, p1x, p1y, p2x, p2y );
	}
}

void PipeCube::figureOutTextures( int face, int p1x, int p1y, int p2x, int p2y )
{
	std::string mat;

	switch( p1y )
	{
		case 0:	//North

			switch( p1x )
			{
				case 0:	//West
					switch( p2y )	//Now check what our second exit is
					{
						case 0:	//The only place it can be in the North is North West
							mat = "NW2NE";
							break;
						case 1:	//The only place it can be is East
							mat = "NW2E";
							break;
						case 2:	//It can be in all three places
							if( p2x == 0 )
								mat = "NW2SW";
							else if( p2x == 1 )
								mat = "NW2S";
							else	//p2x == 2
								mat = "NW2SE";
					}
					break;
				case 1:	//Just North
					switch( p2y )
					{
						case 1:	//It can't be 0, as that isn't a pipe we're having in the game; it can either be E or W
							if( p2x == 0 )	//West
								mat = "N2W";
							else	//East
								mat = "N2E";
							break;
						case 2:	//All three places
							if( p2x == 0 )
								mat = "N2SW";
							else if( p2x == 1 )
								mat = "N2S";
							else	//p2x == 2
								mat = "N2SE";
							break;
					}
					break;
				case 2:	//East
					switch( p2y )
					{
						case 0:	//p2x == 0 is the only option allowed
							mat = "NW2NE";
							break;
						case 1:	//p2x == 0 is still the only option allowed
							mat = "NE2W";
							break;
						case 2:	//All three options
							if( p2x == 0 )
								mat = "NE2SW";
							else if( p2x == 1 )
								mat = "NE2S";
							else	//p2x == 2
								mat = "NE2SE";
							break;
					}
					break;
			}
			break;
		case 1:	//East or West
			switch( p1x )
			{	//1 cannot be a case, that is the middle
				case 0:	//West
					switch( p2y )
					{
						case 0:	//Can be North or North East
							if( p2x == 1 )
								mat = "N2W";
							else	//p2x == 2
								mat = "NE2W";
							break;
						case 1:	//Can only be East
							mat = "W2E";
							break;
						case 2:	//Can be South or South East
							if( p2x == 1 )
								mat = "W2S";
							else	//p2x == 2
								mat = "W2SE";
							break;
					}
					break;
				case 2:	//East
					switch( p2y )
					{
						case 0:	//Can be North or North West
							if( p2x == 0 )
								mat = "NW2E";
							else	//p2x == 1
								mat = "N2E";
							break;
						case 1:	//Can only be West
							mat = "W2E";
							break;
						case 2:	//Can be South or South West
							if( p2x == 0 )
								mat = "E2SW";
							else	//p2x == 1
								mat = "E2S";
							break;
					}
					break;
			}
			break;
		case 2:	//South
			switch( p1x )
			{
				case 0: //West
					switch( p2y )
					{
						case 0:
							if( p2x == 0 )
								mat = "NW2SW";
							else if( p2x == 1 )
								mat = "N2SW";
							else	//p2x == 2
								mat = "NE2SW";
							break;
						case 1:	//East is our only option, p2x == 2
							mat = "E2SW";
							break;
						case 2:	//South East is our only option, p2x == 2
							mat = "SW2SE";
							break;
					}
					break;
				case 1:	//Just South
					switch( p2y )
					{	//Case will never be 2, it is not allowed
						case 0:
							if( p2x == 0 )
								mat = "NW2S";
							else if( p2x == 1 )
								mat = "N2S";
							else	//p2x == 2
								mat = "NE2S";
							break;
						case 1:
							if( p2x == 0 )
								mat = "W2S";
							else	//p2x == 2
								mat = "E2S";
							break;
					}
					break;
				case 2:	//East
					switch( p2y )
					{
						case 0:
							if( p2x == 0 )
								mat = "NW2SE";
							else if( p2x == 1 )
								mat = "N2SE";
							else	//p2x == 2
								mat = "NE2SE";
							break;
						case 1:	//Only option is West
							mat = "W2SE";
							break;
						case 2:	//Only option is South West
							mat = "SW2SE";
							break;
					}
					break;
			}
			break;
	}

	//DEBUGGING RIGHT NOW!!!
//	mat = "W2E";

/*	//HARDCODING FOR RIGHT NOW!!!
	std::list<Ogre::MaterialPtr>::iterator it;
	it = materials->end();
	Ogre::MaterialPtr matPtr = (&it);
*/
	
	//Ogre::MaterialPtr matPtr = pipeMaterials.front();
/*
	switch( mat)
	{
		case "SW2SE":
			
	}
*/

/* EVERYTHING SHOULD BE CORRECT NOW WITH THE ORIENTATION
	//DEBUG

	switch( face )
	{
		case 0:	//faceA
			faceA->setMaterialName("0");
			break;
		case 1:	//faceB
			faceB->setMaterialName("1");
			break;
		case 2:	//faceC
			faceC->setMaterialName("2");
			break;
		case 3:	//faceD
			faceD->setMaterialName("3");
			break;
		case 4:	//faceE
			faceE->setMaterialName("4");
			break;
		case 5:	//faceF
			faceF->setMaterialName("5");
			break;
	}
*/
/*
	/*switch( face )
	{
		case 0:	//faceA
			faceA->setMaterial(matPtr);
			break;
		case 1:	//faceB
			faceB->setMaterial(matPtr);
			break;
		case 2:	//faceC
			faceC->setMaterial(matPtr);
			break;
		case 3:	//faceD
			faceD->setMaterial(matPtr);
			break;
		case 4:	//faceE
			faceE->setMaterial(matPtr);
			break;
		case 5:	//faceF
			faceF->setMaterial(matPtr);
			break;
	}*/

	switch( face )
	{
		case 0:	//faceA
			faceA->setMaterialName(mat);
			break;
		case 1:	//faceB
			faceB->setMaterialName(mat);
			break;
		case 2:	//faceC
			faceC->setMaterialName(mat);
			break;
		case 3:	//faceD
			faceD->setMaterialName(mat);
			break;
		case 4:	//faceE
			faceE->setMaterialName(mat);
			break;
		case 5:	//faceF
			faceF->setMaterialName(mat);
			break;
	}
}

void PipeCube::rotateFacePlaceHolder(char axis, bool clockwise)
{
	//axis: x, y, z

	int t1, a, b, c, d;

	switch(clockwise)
	{
		case false: //counterclockwise rotation
			switch(axis)
			{
			case('x'):
				//Transformation looks like this:
				//[0][1][2][3][4][5] -> [5][1][4][3][0][2]
				/*
						+---+						+---+
						| 5 |						| 2 |
					+---+---+---+				+---+---+---+
					| 3 | 0 | 1 |		----->	| 3 | 5 | 1 |
					+---+---+---+				+---+---+---+
						| 4 |						| 0 |
						+---+						+---+
						| 2 |						| 4 |
						+---+						+---+
				*/
				a = 0, b = 5, c = 2, d = 4; break;
			case('y'):
				//Transformation looks like this:
				//[0][1][2][3][4][5] -> [0][4][2][5][3][1]
				/*
						+---+						+---+
						| 5 |						| 1 |
					+---+---+---+				+---+---+---+
					| 3 | 0 | 1 |		----->	| 5 | 0 | 4 |
					+---+---+---+				+---+---+---+
						| 4 |						| 3 |
						+---+						+---+
						| 2 |						| 2 |
						+---+						+---+
				*/
				a = 1, b = 4, c = 3, d = 5; break;
			case('z'):
				//Transformation looks like this:
				//[0][1][2][3][4][5] -> [1][2][3][0][4][5]
				/*
						+---+						+---+
						| 5 |						| 5 |
					+---+---+---+				+---+---+---+
					| 3 | 0 | 1 |		----->	| 0 | 1 | 2 |
					+---+---+---+				+---+---+---+
						| 4 |						| 4 |
						+---+						+---+
						| 2 |						| 3 |
						+---+						+---+
				*/
				a = 0, b = 1, c = 2, d = 3; break;
			}
			break;
		case true: //clockwise rotation
			switch(axis)
			{
			case('x'):
				//Transformation looks like this:
				//[0][1][2][3][4][5] -> [4][1][5][3][2][0] OR
				/*
						+---+						+---+
						| 5 |						| 0 |
					+---+---+---+				+---+---+---+
					| 3 | 0 | 1 |		----->	| 3 | 4 | 1 |
					+---+---+---+				+---+---+---+
						| 4 |						| 2 |
						+---+						+---+
						| 2 |						| 5 |
						+---+						+---+
				*/
				a = 0, b = 4, c = 2, d = 5; break;
			case('y'):
				//Transformation looks like this:
				//[0][1][2][3][4][5] -> [0][5][2][4][1][3]
				/*
						+---+						+---+
						| 5 |						| 3 |
					+---+---+---+				+---+---+---+
					| 3 | 0 | 1 |		----->	| 4 | 0 | 5 |
					+---+---+---+				+---+---+---+
						| 4 |						| 1 |
						+---+						+---+
						| 2 |						| 2 |
						+---+						+---+
				*/
				a = 1, b = 5, c = 3, d = 4; break;
			case('z'):
				//Transformation looks like this:
				//[0][1][2][3][4][5] -> [3][0][1][2][4][5]
				/*
						+---+						+---+
						| 5 |						| 5 |
					+---+---+---+				+---+---+---+
					| 3 | 0 | 1 |		----->	| 2 | 3 | 0 |
					+---+---+---+				+---+---+---+
						| 4 |						| 4 |
						+---+						+---+
						| 2 |						| 1 |
						+---+						+---+
				*/
				a = 0, b = 3, c = 2, d = 1; break;
			}
			break;
	}

	t1 = facePlaceHolder[a];
	facePlaceHolder[a] = facePlaceHolder[b];
	facePlaceHolder[b] = facePlaceHolder[c];
	facePlaceHolder[c] = facePlaceHolder[d];
	facePlaceHolder[d] = t1;
}

/* the following code is replaced by the simplified method above it (it was a lot of code, 
	so i wanted to consult you before just DELETING it... lol
void PipeCube::rotateXFacePlaceHolder(bool clockwise)
{
	int t1, t2;

	if(clockwise)
	{
		//Transformation looks like this:
		//[0][1][2][3][4][5] -> [4][1][5][3][2][0] OR
		
				+---+						+---+
				| 5 |						| 0 |
			+---+---+---+				+---+---+---+
			| 3 | 0 | 1 |		----->	| 3 | 4 | 1 |
			+---+---+---+				+---+---+---+
			    | 4 |						| 2 |
				+---+						+---+
				| 2 |						| 5 |
				+---+						+---+
		

		t1 = facePlaceHolder[0];
		facePlaceHolder[0] = facePlaceHolder[4];
		t2 = facePlaceHolder[5];
		facePlaceHolder[5] = t1;
		t1 = facePlaceHolder[2];
		facePlaceHolder[2] = t2;
		facePlaceHolder[4] = t1;
	}
	else //counterclockwise
	{
		//Transformation looks like this:
		//[0][1][2][3][4][5] -> [5][1][4][3][0][2]
		/*
				+---+						+---+
				| 5 |						| 2 |
			+---+---+---+				+---+---+---+
			| 3 | 0 | 1 |		----->	| 3 | 5 | 1 |
			+---+---+---+				+---+---+---+
			    | 4 |						| 0 |
				+---+						+---+
				| 2 |						| 4 |
				+---+						+---+
		

		t1 = facePlaceHolder[0];
		facePlaceHolder[0] = facePlaceHolder[5];
		t2 = facePlaceHolder[4];
		facePlaceHolder[4] = t1;
		t1 = facePlaceHolder[2];
		facePlaceHolder[2] = t2;
		facePlaceHolder[5] = t1;
	}
}

void PipeCube::rotateYFacePlaceHolder(bool clockwise)
{
	int t1, t2;

	if(clockwise)
	{
		//Transformation looks like this:
		//[0][1][2][3][4][5] -> [0][5][2][4][1][3]
		/*
				+---+						+---+
				| 5 |						| 3 |
			+---+---+---+				+---+---+---+
			| 3 | 0 | 1 |		----->	| 4 | 0 | 5 |
			+---+---+---+				+---+---+---+
			    | 4 |						| 1 |
				+---+						+---+
				| 2 |						| 2 |
				+---+						+---+
		

		t1 = facePlaceHolder[1];
		facePlaceHolder[1] = facePlaceHolder[5];
		t2 = facePlaceHolder[4];
		facePlaceHolder[4] = t1;
		t1 = facePlaceHolder[3];
		facePlaceHolder[3] = t2;
		facePlaceHolder[5] = t1;
	}
	else //counterclockwise
	{
		//Transformation looks like this:
		//[0][1][2][3][4][5] -> [0][4][2][5][3][1]
		/*
				+---+						+---+
				| 5 |						| 1 |
			+---+---+---+				+---+---+---+
			| 3 | 0 | 1 |		----->	| 5 | 0 | 4 |
			+---+---+---+				+---+---+---+
			    | 4 |						| 3 |
				+---+						+---+
				| 2 |						| 2 |
				+---+						+---+
		

		t1 = facePlaceHolder[4];
		facePlaceHolder[4] = facePlaceHolder[3];
		t2 = facePlaceHolder[1];
		facePlaceHolder[1] = t1;
		t1 = facePlaceHolder[5];
		facePlaceHolder[5] = t2;
		facePlaceHolder[3] = t1;
	}
}

void PipeCube::rotateZFacePlaceHolder(bool clockwise)
{
	int t1, t2;

	if(clockwise)
	{
		//Transformation looks like this:
		//[0][1][2][3][4][5] -> [3][0][1][2][4][5]
		/*
				+---+						+---+
				| 5 |						| 5 |
			+---+---+---+				+---+---+---+
			| 3 | 0 | 1 |		----->	| 2 | 3 | 0 |
			+---+---+---+				+---+---+---+
			    | 4 |						| 4 |
				+---+						+---+
				| 2 |						| 1 |
				+---+						+---+
		

		t1 = facePlaceHolder[0];
		facePlaceHolder[0] = facePlaceHolder[3];
		t2 = facePlaceHolder[1];
		facePlaceHolder[1] = t1;
		t1 = facePlaceHolder[2];
		facePlaceHolder[2] = t2;
		facePlaceHolder[3] = t1;
	}
	else //counterclockwise
	{
		//Transformation looks like this:
		//[0][1][2][3][4][5] -> [1][2][4][0][4][5]
		/*
				+---+						+---+
				| 5 |						| 5 |
			+---+---+---+				+---+---+---+
			| 3 | 0 | 1 |		----->	| 0 | 1 | 2 |
			+---+---+---+				+---+---+---+
			    | 4 |						| 4 |
				+---+						+---+
				| 2 |						| 3 |
				+---+						+---+
		

		t1 = facePlaceHolder[0];
		facePlaceHolder[0] = facePlaceHolder[1];
		t2 = facePlaceHolder[3];
		facePlaceHolder[3] = t1;
		t1 = facePlaceHolder[2];
		facePlaceHolder[2] = t2;
		facePlaceHolder[1] = t1;
	}
}
*/

void PipeCube::rotateLeft()
{
	if( !isRotating )
	{
		isRotating = true;
		rotatingLeft = true;

		switch(currentFace)
		{
			case 0:
			{
				if( facePlaceHolder[1] == 1 )
				{
					rotateFace(4, false);
					rotateFace(5, true);
				}
				else if( facePlaceHolder[1] == 3 )
				{
					rotateFace(4, true);
					rotateFace(5, false);
				}
				else if( facePlaceHolder[1] == 5 )
				{
					rotateFace(1, false);
					rotateFace(3, true);
				}
				else
				{
					rotateFace(1, true);
					rotateFace(3, false);
				}
				break;
			}
			case 1:
			{
				if( facePlaceHolder[1] == 2 )
				{
					rotateFace(4, false);
					rotateFace(5, true);
				}
				else if( facePlaceHolder[1] == 0 )
				{
					rotateFace(4, true);
					rotateFace(5, false);
				}
				else if( facePlaceHolder[1] == 5 )
				{
					rotateFace(0, true);
					rotateFace(2, false);
				}
				else
				{
					rotateFace(0, false);
					rotateFace(2, true);
				}
				break;
			}
			case 2:
			{
				if( facePlaceHolder[1] == 3 )
				{
					rotateFace(4, false);
					rotateFace(5, true);
				}
				else if( facePlaceHolder[1] == 1 )
				{
					rotateFace(4, true);
					rotateFace(5, false);
				}
				else if( facePlaceHolder[1] == 4 )
				{
					rotateFace(1, false);
					rotateFace(3, true);
				}
				else
				{
					rotateFace(1, true);
					rotateFace(3, false);
				}
				break;
			}
			case 3:
			{
				if( facePlaceHolder[1] == 0 )
				{
					rotateFace(4, false);
					rotateFace(5, true);
				}
				else if( facePlaceHolder[1] == 2 )
				{
					rotateFace(4, true);
					rotateFace(5, false);
				}
				else if( facePlaceHolder[1] == 5 )
				{
					rotateFace(0, false);
					rotateFace(2, true);
				}
				else
				{
					rotateFace(0, true);
					rotateFace(2, false);
				}
				break;
			}
			case 4:
			{
				if( facePlaceHolder[1] == 1 )
				{
					rotateFace(0, true);
					rotateFace(2, false);
				}
				else if( facePlaceHolder[1] == 3 )
				{
					rotateFace(0, false);
					rotateFace(2, true);
				}
				else if( facePlaceHolder[1] == 2 )
				{
					rotateFace(1, true);
					rotateFace(3, false);
				}
				else
				{
					rotateFace(1, false);
					rotateFace(3, true);
				}
				break;
			}
			case 5:
			{
				if( facePlaceHolder[1] == 1 )
				{
					rotateFace(0, false);
					rotateFace(2, true);
				}
				else if( facePlaceHolder[1] == 3 )
				{
					rotateFace(0, true);
					rotateFace(2, false);
				}
				else if( facePlaceHolder[1] == 0 )
				{
					rotateFace(1, true);
					rotateFace(3, false);
				}
				else
				{
					rotateFace(1, false);
					rotateFace(3, true);
				}
				break;
			}
		}

		//rotateZFacePlaceHolder(false);
		rotateFacePlaceHolder('z', false);
		currentFace = facePlaceHolder[0];
	}
}

void PipeCube::rotateRight()
{
	if( !isRotating )
	{
		isRotating = true;
		rotatingRight = true;

		switch(currentFace)
		{
			case 0:
			{
				if( facePlaceHolder[1] == 1 )
				{
					rotateFace(4, true);
					rotateFace(5, false);
				}
				else if( facePlaceHolder[1] == 3 )
				{
					rotateFace(4, false);
					rotateFace(5, true);
				}
				else if( facePlaceHolder[1] == 5 )
				{
					rotateFace(1, true);
					rotateFace(3, false);
				}
				else
				{
					rotateFace(1, false);
					rotateFace(3, true);
				}
				break;
			}
			case 1:
			{
				if( facePlaceHolder[1] == 2 )
				{
					rotateFace(4, true);
					rotateFace(5, false);
				}
				else if( facePlaceHolder[1] == 0 )
				{
					rotateFace(4, false);
					rotateFace(5, true);
				}
				else if( facePlaceHolder[1] == 5 )
				{
					rotateFace(0, false);
					rotateFace(2, true);
				}
				else
				{
					rotateFace(0, true);
					rotateFace(2, false);
				}
				break;
			}
			case 2:
			{
				if( facePlaceHolder[1] == 3 )
				{
					rotateFace(4, true);
					rotateFace(5, false);
				}
				else if( facePlaceHolder[1] == 1 )
				{
					rotateFace(4, false);
					rotateFace(5, true);
				}
				else if( facePlaceHolder[1] == 4 )
				{
					rotateFace(1, true);
					rotateFace(3, false);
				}
				else
				{
					rotateFace(1, false);
					rotateFace(3, true);
				}
				break;
			}
			case 3:
			{
				if( facePlaceHolder[1] == 0 )
				{
					rotateFace(4, true);
					rotateFace(5, false);
				}
				else if( facePlaceHolder[1] == 2 )
				{
					rotateFace(4, false);
					rotateFace(5, true);
				}
				else if( facePlaceHolder[1] == 5 )
				{
					rotateFace(0, true);
					rotateFace(2, false);
				}
				else
				{
					rotateFace(0, false);
					rotateFace(2, true);
				}
				break;
			}
			case 4:
			{
				if( facePlaceHolder[1] == 1 )
				{
					rotateFace(0, false);
					rotateFace(2, true);
				}
				else if( facePlaceHolder[1] == 3 )
				{
					rotateFace(0, true);
					rotateFace(2, false);
				}
				else if( facePlaceHolder[1] == 2 )
				{
					rotateFace(1, false);
					rotateFace(3, true);
				}
				else
				{
					rotateFace(1, true);
					rotateFace(3, false);
				}
				break;
			}
			case 5:
			{
				if( facePlaceHolder[1] == 1 )
				{
					rotateFace(0, true);
					rotateFace(2, false);
				}
				else if( facePlaceHolder[1] == 3 )
				{
					rotateFace(0, false);
					rotateFace(2, true);
				}
				else if( facePlaceHolder[1] == 0 )
				{
					rotateFace(1, false);
					rotateFace(3, true);
				}
				else
				{
					rotateFace(1, true);
					rotateFace(3, false);
				}
				break;
			}
		}

		//rotateZFacePlaceHolder(true);
		rotateFacePlaceHolder('z', true);
		currentFace = facePlaceHolder[0];
	}
}

void PipeCube::rotateForward()
{
	if( !isRotating )
	{
		isRotating = true;
		rotatingForward = true;

		switch(currentFace)
		{
			case 0:
			{
				if( facePlaceHolder[1] == 1 )
				{
					rotateFace(1, true);
					rotateFace(3, false);
				}
				else if( facePlaceHolder[1] == 3 )
				{
					rotateFace(1, false);
					rotateFace(3, true);
				}
				else if( facePlaceHolder[1] == 5 )
				{
					rotateFace(4, false);
					rotateFace(5, true);
				}
				else
				{
					rotateFace(4, true);
					rotateFace(5, false);
				}
				break;
			}
			case 1:
			{
				if( facePlaceHolder[1] == 2 )
				{
					rotateFace(0, false);
					rotateFace(2, true);
				}
				else if( facePlaceHolder[1] == 0 )
				{
					rotateFace(0, true);
					rotateFace(2, false);
				}
				else if( facePlaceHolder[1] == 5 )
				{
					rotateFace(4, false);
					rotateFace(5, true);
				}
				else
				{
					rotateFace(4, true);
					rotateFace(5, false);
				}
				break;
			}
			case 2:
			{
				if( facePlaceHolder[1] == 3 )
				{
					rotateFace(1, false);
					rotateFace(3, true);
				}
				else if( facePlaceHolder[1] == 1 )
				{
					rotateFace(1, true);
					rotateFace(3, false);
				}
				else if( facePlaceHolder[1] == 4 )
				{
					rotateFace(4, true);
					rotateFace(5, false);
				}
				else
				{
					rotateFace(4, false);
					rotateFace(5, true);
				}
				break;
			}
			case 3:
			{
				if( facePlaceHolder[1] == 0 )
				{
					rotateFace(0, true);
					rotateFace(2, false);
				}
				else if( facePlaceHolder[1] == 2 )
				{
					rotateFace(0, false);
					rotateFace(2, true);
				}
				else if( facePlaceHolder[1] == 5 )
				{
					rotateFace(4, false);
					rotateFace(5, true);
				}
				else
				{
					rotateFace(4, true);
					rotateFace(5, false);
				}
				break;
			}
			case 4:
			{
				if( facePlaceHolder[1] == 1 )
				{
					rotateFace(1, true);
					rotateFace(3, false);
				}
				else if( facePlaceHolder[1] == 3 )
				{
					rotateFace(1, false);
					rotateFace(3, true);
				}
				else if( facePlaceHolder[1] == 2 )
				{
					rotateFace(0, false);
					rotateFace(2, true);
				}
				else
				{
					rotateFace(0, true);
					rotateFace(2, false);
				}
				break;
			}
			case 5:
			{
				if( facePlaceHolder[1] == 1 )
				{
					rotateFace(1, true);
					rotateFace(3, false);
				}
				else if( facePlaceHolder[1] == 3 )
				{
					rotateFace(1, false);
					rotateFace(3, true);
				}
				else if( facePlaceHolder[1] == 0 )
				{
					rotateFace(0, true);
					rotateFace(2, false);
				}
				else
				{
					rotateFace(0, false);
					rotateFace(2, true);
				}
				break;
			}
		}

		//rotateXFacePlaceHolder(true);
		rotateFacePlaceHolder('x', true);
		currentFace = facePlaceHolder[0];
	}
}

void PipeCube::rotateBackward()
{
	if( !isRotating )
	{
		isRotating = true;
		rotatingBackward = true;

		switch(currentFace)
		{
			case 0:
			{
				if( facePlaceHolder[1] == 1 )
				{
					rotateFace(1, false);
					rotateFace(3, true);
				}
				else if( facePlaceHolder[1] == 3 )
				{
					rotateFace(1, true);
					rotateFace(3, false);
				}
				else if( facePlaceHolder[1] == 5 )
				{
					rotateFace(4, true);
					rotateFace(5, false);
				}
				else
				{
					rotateFace(4, false);
					rotateFace(5, true);
				}
				break;
			}
			case 1:
			{
				if( facePlaceHolder[1] == 2 )
				{
					rotateFace(0, true);
					rotateFace(2, false);
				}
				else if( facePlaceHolder[1] == 0 )
				{
					rotateFace(0, false);
					rotateFace(2, true);
				}
				else if( facePlaceHolder[1] == 5 )
				{
					rotateFace(4, true);
					rotateFace(5, false);
				}
				else
				{
					rotateFace(4, false);
					rotateFace(5, true);
				}
				break;
			}
			case 2:
			{
				if( facePlaceHolder[1] == 3 )
				{
					rotateFace(1, true);
					rotateFace(3, false);
				}
				else if( facePlaceHolder[1] == 1 )
				{
					rotateFace(1, false);
					rotateFace(3, true);
				}
				else if( facePlaceHolder[1] == 4 )
				{
					rotateFace(4, false);
					rotateFace(5, true);
				}
				else
				{
					rotateFace(4, true);
					rotateFace(5, false);
				}
				break;
			}
			case 3:
			{
				if( facePlaceHolder[1] == 0 )
				{
					rotateFace(0, false);
					rotateFace(2, true);
				}
				else if( facePlaceHolder[1] == 2 )
				{
					rotateFace(0, true);
					rotateFace(2, false);
				}
				else if( facePlaceHolder[1] == 5 )
				{
					rotateFace(4, true);
					rotateFace(5, false);
				}
				else
				{
					rotateFace(4, false);
					rotateFace(5, true);
				}
				break;
			}
			case 4:
			{
				if( facePlaceHolder[1] == 1 )
				{
					rotateFace(1, false);
					rotateFace(3, true);
				}
				else if( facePlaceHolder[1] == 3 )
				{
					rotateFace(1, true);
					rotateFace(3, false);
				}
				else if( facePlaceHolder[1] == 2 )
				{
					rotateFace(0, true);
					rotateFace(2, false);
				}
				else
				{
					rotateFace(0, false);
					rotateFace(2, true);
				}
				break;
			}
			case 5:
			{
				if( facePlaceHolder[1] == 1 )
				{
					rotateFace(1, false);
					rotateFace(3, true);
				}
				else if( facePlaceHolder[1] == 3 )
				{
					rotateFace(1, true);
					rotateFace(3, false);
				}
				else if( facePlaceHolder[1] == 0 )
				{
					rotateFace(0, false);
					rotateFace(2, true);
				}
				else
				{
					rotateFace(0, true);
					rotateFace(2, false);
				}
				break;
			}
		}

//		rotateXFacePlaceHolder(false);
		rotateFacePlaceHolder('x', false);
		currentFace = facePlaceHolder[0];
	}
}

void PipeCube::rotateClock()
{
	if( !isRotating )
	{
		isRotating = true;
		rotatingClock = true;

		switch(currentFace)
		{
			case 0:
			{
				rotateFace(0, true);
				rotateFace(2, false);
				break;
			}
			case 1:
			{
				rotateFace(1, true);
				rotateFace(3, false);
				break;
			}
			case 2:
			{
				rotateFace(0, false);
				rotateFace(2, true);
				break;
			}
			case 3:
			{
				rotateFace(1, false);
				rotateFace(3, true);
				break;
			}
			case 4:
			{
				rotateFace(4, true);
				rotateFace(5, false);
				break;
			}
			case 5:
			{
				rotateFace(4, false);
				rotateFace(5, true);
				break;
			}
		}

//	rotateYFacePlaceHolder(true);
		rotateFacePlaceHolder('y', true);
		//Don't need to change the current face because this doesn't change the current face, just the orientation
	}
}

void PipeCube::rotateCountClock()
{
	if( !isRotating )
	{
		isRotating = true;
		rotatingCountClock = true;

		switch(currentFace)
		{
			case 0:
			{
				rotateFace(0, false);
				rotateFace(2, true);
				break;
			}
			case 1:
			{
				rotateFace(1, false);
				rotateFace(3, true);
				break;
			}
			case 2:
			{
				rotateFace(0, true);
				rotateFace(2, false);
				break;
			}
			case 3:
			{
				rotateFace(1, true);
				rotateFace(3, false);
				break;
			}
			case 4:
			{
				rotateFace(4, false);
				rotateFace(5, true);
				break;
			}
			case 5:
			{
				rotateFace(4, true);
				rotateFace(5, false);
				break;
			}
		}

//	rotateYFacePlaceHolder(false);
		rotateFacePlaceHolder('y', false);
		//Don't need to change the current face because this doesn't change the current face, just the orientation
	}
}

void PipeCube::rotateFace( int which, bool clockwise )
{
	bool temp[3][3];
	for( int i = 0; i < 3; i++ )	//Just make a copy of faces[which]
	{
		for(int j = 0; j < 3; j++)
			temp[i][j] = faces[which][i][j];
	}
	/*	  0   1   2					  0   1   2			  0   1   2
		+ - + - + - +				+ - + - + - +		+ - + - + - +
	0 = | T | F | F | clockwise	  0 | T | F | T |	  0 | 20| 10| 00|
		+ - + - + - +	 =>			+ - + - + - +	=   + - + - + - +
	1 = | F | F | F |			  1 | F | F | F |     1 | 21| 11| 01|
		+ - + - + - +				+ - + - + - +       + - + - + - +
	2 = | T | F | F |			  2 | F | F | F |     2 | 22| 12| 02|
		+ - + - + - +				+ - + - + - +       + - + - + - +
	*/

	if( clockwise )
	{
		faces[which][0][0] = temp[2][0];	//top
		faces[which][0][1] = temp[1][0];
		faces[which][0][2] = temp[0][0];

		faces[which][1][2] = temp[0][1];	//right
		faces[which][2][2] = temp[0][2];

		faces[which][2][1] = temp[1][2];	//bottom
		faces[which][2][0] = temp[2][2];

		faces[which][1][0] = temp[2][1];	//left
	}
	else
	{
		/*
		  0   1   2					  0   1   2			  0   1   2
		+ - + - + - +				+ - + - + - +		+ - + - + - +
	0 = | T | F | F | cclockwise  0 | F | F | F |	  0 | 02| 12| 22|
		+ - + - + - +	 =>			+ - + - + - +	=   + - + - + - +
	1 = | F | F | F |			  1 | F | F | F |     1 | 01| 11| 21|
		+ - + - + - +				+ - + - + - +       + - + - + - +
	2 = | T | F | F |			  2 | T | F | T |     2 | 00| 10| 20|
		+ - + - + - +				+ - + - + - +       + - + - + - +
		*/
		faces[which][0][0] = temp[0][2];	//top
		faces[which][0][1] = temp[1][2];
		faces[which][0][2] = temp[2][2];

		faces[which][1][2] = temp[2][1];	//right
		faces[which][2][2] = temp[2][0];

		faces[which][2][1] = temp[1][0];	//bottom
		faces[which][2][0] = temp[0][0];

		faces[which][1][0] = temp[0][1];	//left
	}
}

void PipeCube::update(Ogre::Real deltaTime)
{
	if( isRotating )
		updateRotate(deltaTime);
}

void PipeCube::updateRotate(Ogre::Real deltaTime)
{
	int rotationDegrees = deltaTime*360 + .5;
	if(rotatingLeft)
	{
		if(degreesRotated < 90)
		{
			double temp = degreesRotated + rotationDegrees;
			if(temp >= 90)		//Too much rotation, just rotate the rest of the degrees needed to get to -90
			{
				isRotating = false;
				rotatingLeft = false;
				mCubeNode->roll( Degree( 90 - degreesRotated ), Node::TS_WORLD );
				degreesRotated = 0;
			}
			else
			{
				degreesRotated = temp;
				mCubeNode->roll( Degree( rotationDegrees ), Node::TS_WORLD );
			}
		}
		else
		{
			isRotating = false;
			rotatingLeft = false;
			degreesRotated = 0;
		}
	}
	else if(rotatingRight)
	{
		if(degreesRotated > -90)
		{
			double temp = degreesRotated - rotationDegrees;
			if(temp <= -90)		//Too much rotation, just rotate the rest of the degrees needed to get to -90
			{
				isRotating = false;
				rotatingRight = false;
				mCubeNode->roll( Degree( -90 - degreesRotated ), Node::TS_WORLD );
				degreesRotated = 0;
			}
			else
			{
				degreesRotated = temp;
				mCubeNode->roll( Degree( -rotationDegrees ), Node::TS_WORLD );
			}
		}
		else
		{
			isRotating = false;
			rotatingRight = false;
			degreesRotated = 0;
		}
	}
	else if(rotatingForward)
	{
		if(degreesRotated > -90)
		{
			double temp = degreesRotated - rotationDegrees;
			if(temp <= -90)		//Too much rotation, just rotate the rest of the degrees needed to get to -90
			{
				isRotating = false;
				rotatingForward = false;
				mCubeNode->pitch( Degree( -90 - degreesRotated ), Node::TS_WORLD );
				degreesRotated = 0;
			}
			else
			{
				degreesRotated = temp;
				mCubeNode->pitch( Degree( -rotationDegrees ), Node::TS_WORLD );
			}
		}
		else
		{
			isRotating = false;
			rotatingForward = false;
			degreesRotated = 0;
		}
	}
	else if(rotatingBackward)
	{
		if(degreesRotated < 90)
		{
			double temp = degreesRotated + rotationDegrees;
			if(temp >= 90)		//Too much rotation, just rotate the rest of the degrees needed to get to -90
			{
				isRotating = false;
				rotatingBackward = false;
				mCubeNode->pitch( Degree( 90 - degreesRotated ), Node::TS_WORLD );
				degreesRotated = 0;
			}
			else
			{
				degreesRotated = temp;
				mCubeNode->pitch( Degree( rotationDegrees ), Node::TS_WORLD );
			}
		}
		else
		{
			isRotating = false;
			rotatingBackward = false;
			degreesRotated = 0;
		}
	}
	else if(rotatingClock)
	{
		if(degreesRotated > -90)
		{
			double temp = degreesRotated - rotationDegrees;
			if(temp <= -90)		//Too much rotation, just rotate the rest of the degrees needed to get to -90
			{
				isRotating = false;
				rotatingClock = false;
				mCubeNode->yaw( Degree( -90 - degreesRotated ), Node::TS_WORLD );
				degreesRotated = 0;
			}
			else
			{
				degreesRotated = temp;
				mCubeNode->yaw( Degree( -rotationDegrees ), Node::TS_WORLD );
			}
		}
		else
		{
			isRotating = false;
			rotatingClock = false;
			degreesRotated = 0;
		}
		
	}
	else if(rotatingCountClock)
	{
		if(degreesRotated < 90)
		{
			double temp = degreesRotated + rotationDegrees;
			if(temp >= 90)		//Too much rotation, just rotate the rest of the degrees needed to get to -90
			{
				isRotating = false;
				rotatingCountClock = false;
				mCubeNode->yaw( Degree( 90 - degreesRotated ), Node::TS_WORLD );
				degreesRotated = 0;
			}
			else
			{
				degreesRotated = temp;
				mCubeNode->yaw( Degree( rotationDegrees ), Node::TS_WORLD );
			}
		}
		else
		{
			isRotating = false;
			rotatingCountClock = false;
			degreesRotated = 0;
		}
	}
}

int* PipeCube::getCurrentFace()
{
	int* exits = new int[4];
	int count = 0;
	for( int i = 0; i < 3; i++ )
	{
		for( int j = 0; j < 3; j++ )
		{
			if( faces[currentFace][i][j] )
			{
				*(exits + count++) = i;
				*(exits + count++) = j;
			}	
		}
	}

	return exits;
}
/*
HouseCube* PipeCube::changeToHouseCube() //Alright, so this doesn't delete the current object.  We'll have to remember to do that when we call this function!
{
	Vector3 location = mCubeNode->getPosition();
	sceneMgr->destroyEntity(mCubeEntity);
	return new HouseCube(iD, location, mCubeNode);
}*/

void PipeCube::hideAllTextures()
{
	faceA->setVisible(false);
	faceB->setVisible(false);
	faceC->setVisible(false);
	faceD->setVisible(false);
	faceE->setVisible(false);
	faceF->setVisible(false);
}

void PipeCube::showAllTextures()
{
	faceA->setVisible(true);
	faceB->setVisible(true);
	faceC->setVisible(true);
	faceD->setVisible(true);
	faceE->setVisible(true);
	faceF->setVisible(true);
}